﻿using System;
using Microsoft.Xna.Framework;

namespace MaterialEditor
{
    public class PanNode : Node
    {
        InputSlot A
        {
            get { return input[0]; }
        }

        InputSlot Offset
        {
            get { return input[1]; }
        }
        private NodeValueType[][] _acceptTypes;
        public override NodeValueType[][] acceptTypes
        {
            get { return _acceptTypes; }
        }

        public PanNode(int x, int y)
            : base(x, y)
        {
            input = new InputSlot[]
            {
                new InputSlot(this, null, "A"),
                new InputSlot(this, null,  "Offset"),
            };

            _acceptTypes = new NodeValueType[][]
            {
                new NodeValueType[] { NodeValueType.ValueTexture },
                new NodeValueType[] { NodeValueType.ValueVector2 },
            };

            output = new InputSlot(this, null, "");

            A.Connected += A_Connected;
            Offset.Connected += Offset_Connected;

            A.Disconnected += A_Disconnected;
            Offset.Disconnected += Offset_Disconnected;

            Name = "Pan Texture";

            A.ValueChanged += UpdateValue;
            Offset.ValueChanged += UpdateValue;

        }

        void Offset_Disconnected()
        {
            if (Offset.value != null)
            {
                Offset.value.ValueChanged -= UpdateValue;
                Offset.value.TimeChanged -= UpdateTime;
            }

            _result = null;
        }

        void A_Disconnected()
        {
            if (A.value != null)
                A.value.ValueChanged -= UpdateValue;

            _result = null;
        }
        
        void Offset_Connected()
        {
            if (Offset.value.type != NodeValueType.ValueVector2)
            {
                Offset.connector.Disconnect();
                return;
            }
            Offset.value.ValueChanged += UpdateValue;
            Offset.value.TimeChanged += UpdateTime;

            UpdateValue();
        }

        void A_Connected()
        {
            if (A.value.Value.GetType() != typeof(TextureContainer))
            {
                A.connector.Disconnect();
                return;
            }

            A.value.ValueChanged += UpdateValue;

            UpdateValue();
        }

        private void UpdateValue()
        {
            if (!Offset.isConnected || !A.isConnected)
            {
                _result = null;
                return;
            }
            TextureContainer container = new TextureContainer(A.value.Value as TextureContainer);       
            pan = new Panning();
            pan.offset = (Vector2)Offset.value.Value;
            container.texture.effects += pan;

            _result = new NodeValue(container);
        }

        private NodeValue _result;
        public override NodeValue Result
        {
            get { return _result; }
        }
        public override object Clone()
        {
            PanNode n = new PanNode((int)position.X, (int)position.Y);
            if (Result != null)
                n._result = new NodeValue(_result.Value);

            return n;
        }

        Panning pan;
        private void UpdateTime()
        {
            if (!Offset.isConnected || !A.isConnected)
                return;

            pan.offset = Offset.value.AsVector2();
        }
    }
}